<template>
  <div ref="myScroll" class="my-scroll" :class="[scrollState?'prohibit':'allow']" @scroll.passive="onScroll($event)" @touchstart="touchStart($event)" @touchmove="touchMove($event)" @touchend="touchEnd($event)">
    <div class="scroll-top" :style="{height:top+'px'}">
      <div v-if="aspect==2">
        <p v-if="state==6">
          下拉刷新
        </p>
        <p v-if="state==1">
          <i class="el-icon-loading" />
          <br>
          刷新中
        </p>
        <p v-if="state==2">松开刷新</p>
        <p v-if="state==3">
          <i class="el-icon-loading" />
          <br>
          刷新完成
        </p>
      </div>
    </div>
    <!-- top -->
    <div class="scroll-list" :style="{ transform: 'translate3d(0, ' + top + 'px, 0)'}">
      <slot name="scrollList" />
      <div class="scroll-bottom">
        <div v-if="state==4">没有更多</div>
        <div v-if="state==5">加载完成</div>
        <div v-if="state==7">没有更多</div>
      </div>
    </div>
  </div>
</template>
<script type="text/javascript">
import tween from '../commonTemplate/tween'
import Load from './assets/Load.gif'
export default {
  name: 'MyScroll',
  props: {
    'page': {
      type: Object // counter:当前页  pageStart:开始页数  pageEnd:结束页数  total:总页数
    },
    'onRefresh': { // 刷新回调
      type: Function,
      require: true
    },
    'onPull': { // 加载回调
      type: Function,
      require: true
    },
    'getScrollTop': { // 获取滚动条位置
      type: Function
    },
    'setScrollPage': { // 改变滚动条位置
      type: Function
    },
    'scrollState': {// 是否可滑动
      type: Boolean,
      require: true
    }
  },
  data() {
    return {
      Load,
      pageX: 0,
      pageY: 0,
      state: 0,
      scrollPosition: 0,
      myScroll: null,
      myScrollList: null,
      top: 0,
      aspect: 0, // 1:向下 2:向上
      listHeight: 0
 			}
  },
  created() {

  },
  mounted() {
    this.myScroll = this.$refs.myScroll // 获取滑条dom
    this.myScrollList = this.myScroll.children[1] // 获取列表dom
  },
  methods: {
    ScrollTop(top) { // 修改滚动条位置
      this.myScroll.scrollTop = top
    },
    /*
			 * 刷新中：1
			 * 松开刷新：2
			 * 刷新完成：3
			 * 加载中：4
			 * 加载完成：5
			 * 下拉刷新：6
			 * 没有更多：7
			 */
    setState(index) { // 修改状态
      this.state = index
		      if (index == 5 || index == 3) {
        setTimeout(() => {
          this.state = 0
          let timer = null
          const that = this
          var b = 50; var c = 100; var d = 100; var t = 0
          cancelAnimationFrame(timer)
          timer = requestAnimationFrame(function fn() {
            var oTop = that.top
            if (that.top > 0) {
              that.top = Math.ceil(tween.Quart.easeInOut(10, oTop, 8, 10)) - 15
              timer = requestAnimationFrame(fn)
            } else {
              cancelAnimationFrame(timer)
              that.top = 0
            }
          })
        }, 500)
      }
    },
    touchStart(e) { // 触摸事件
      this.pageX = e.targetTouches[0].pageX
      this.pageY = e.targetTouches[0].pageY
    },
    touchMove(e) { // 触摸滑动事件
      this.scrollPosition = this.myScroll.scrollTop // 获取滚动条位置
      if (this.scrollState && e.targetTouches[0].pageY > this.pageY) { // 向上滑动
        this.aspect = 2
        if (this.myScroll.scrollTop == 0) {
          const diff = e.targetTouches[0].pageY - this.pageY - this.scrollPosition
          this.top = Math.pow(diff, 0.9)
          const ranget = diff / document.body.clientHeight * 100 // 计算在屏幕上滑动了多少
          if (ranget > 20) {
            this.state = 2
          } else if (ranget < 15) {
            this.state = 6
          }
						 e.preventDefault()
        }
      } else if (this.scrollState && this.state != 4) { // 向上滑动
        this.aspect = 1
      }
    },
    touchEnd(e) {
      if (this.aspect == 2 && this.state == 2 || this.state == 1) { // 上拉处理
        this.top = 100
        this.state = 1
        this.topCallback()
      } else if (this.aspect == 2) {
        this.state = 0
        this.top = 0
      }
    },
    onScroll(e) {
      const listHeight = this.myScrollList.offsetHeight 总高度
      const listScrollTop = e.target.scrollTop + this.myScroll.offsetHeight // 当前滚动条位置

      if (this.state == 0 && listHeight - listScrollTop < 100) {
        this.bottomCallback()
      }

      if (this.getScrollTop) this.getScrollTop(e.target.scrollTop) // 返回X，Y
    },
    topCallback() { // 刷新回调
      this.onRefresh(this.state)
    },
    bottomCallback() { // 加载回调
      if (this.state != 7) {
        this.state = 4
        this.onPull(this.state)
      }
    }
  }
}
</script>
<style lang="scss" scoped>
	.allow{
		overflow:hidden;
		height: auto;
	}
	.prohibit{
		max-width: 100%;
		max-height: 100%;
	    height: 100%;
		overflow:hidden;
		overflow-y: scroll;
		-webkit-overflow-scrolling: touch;
		will-change: transform;
	    transition: all 450ms;
	    backface-visibility: hidden;
	    perspective: 1000;
	}
	.my-scroll{
	    position: relative;
			color: rgb(0, 113, 206);
	    .scroll-top{
	    	text-align: center;
	    	display:flex;
	    	position:absolute;
	    	top:0;
	    	left:0;
			width:100%;
			overflow: hidden;
	    	div{
	    		display:flex;
				height:auto;
	    		width:100%;
	    		justify-content: center;
	    		align-items:center;
	    		flex-wrap: wrap;
	    		// i{
	    		// 	flex:1 0 100%;
					// display:block;
					// height: 0.4rem;
	    		// }
	    		// img{
	    		// 	width:0.6rem;
	    		// }
				p{
					flex:1 0 100%;
				}
	    	}
	    }
		.scroll-list{
			overflow:hidden;
			min-height: 100%;
		}
		.scroll-bottom{
			text-align: center;
			line-height: 40px;
		}
	}
</style>
